package com.example.animationdrawabledemo;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;

public class NewBubbleDrawable extends Drawable {

	private static final String TAG = NewBubbleDrawable.class.getSimpleName();
	private NewBubbleDrawableState mBubbleDrawableState;
	private int mTargetDensity;
	private Bitmap mutable;
	private Bitmap mask,bgNor,grain;
	private Canvas canvas;
	private NinePatchDrawable ninePatchDrawable,maskNinePatchDrawable;
	private Rect rect;
	public NewBubbleDrawable(Context context) {
		super();
		// TODO Auto-generated constructor stub
		mask = BitmapFactory.decodeResource(context.getResources(), R.drawable.aio_friend_bg_mask);
		bgNor = BitmapFactory.decodeResource(context.getResources(), R.drawable.aio_friend_bg_nor);
		ninePatchDrawable = new NinePatchDrawable(context.getResources(), bgNor, bgNor.getNinePatchChunk(), new Rect(), null);
		maskNinePatchDrawable = new NinePatchDrawable(context.getResources(), mask, mask.getNinePatchChunk(), new Rect(), null);
		grain =BitmapFactory.decodeResource(context.getResources(), R.drawable.aio_textrue_nor);
		
		mBubbleDrawableState = new NewBubbleDrawableState(mask,bgNor,grain);
		mBubbleDrawableState.mTargetDensity = mTargetDensity;
	}
	
	@Override
	public int getChangingConfigurations() {
		return super.getChangingConfigurations() | mBubbleDrawableState.mChangingConfigurations;
	}
	
	@Override
	protected void onBoundsChange(Rect bounds) {
		super.onBoundsChange(bounds);
		mutable = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888);
		canvas = new Canvas(mutable);
		rect = new Rect(0, 0, bounds.width(), bounds.height());
	}

	
	private long startTime = 0;
	@Override
	public void draw(Canvas onDrawCanvas) {
		if(rect == null){
			return;
		}
		Log.v(TAG, "width:"+rect.width()+"height:"+rect.height());
		startTime = System.currentTimeMillis();
		maskNinePatchDrawable.setBounds(rect);
		maskNinePatchDrawable.draw(canvas);
		Log.v(TAG, "1:"+(System.currentTimeMillis()-startTime));
//		createRepeater(rect.width(),rect.height(),mBubbleDrawableState.mGrain,canvas,mBubbleDrawableState.mPaint);
		canvas.drawRect(rect, mBubbleDrawableState.mPaint);
		Log.v(TAG, "2:"+(System.currentTimeMillis()-startTime));
		ninePatchDrawable.setBounds(rect);
		ninePatchDrawable.draw(canvas);
		Log.v(TAG, "3:"+(System.currentTimeMillis()-startTime));
		onDrawCanvas.drawBitmap(mutable, 0, 0, null);
		Log.v(TAG, "4:"+(System.currentTimeMillis()-startTime));
	}

	@Override
	public void setAlpha(int alpha) {

	}

	@Override
	public void setColorFilter(ColorFilter cf) {

	}

	@Override
	public int getOpacity() {
		// TODO Auto-generated method stub
		return  android.graphics.PixelFormat.TRANSPARENT;
	}
	
	@Override
	public final ConstantState getConstantState() {
		mBubbleDrawableState.mChangingConfigurations = getChangingConfigurations();
		return mBubbleDrawableState;
	}

	final static class NewBubbleDrawableState extends ConstantState {
		Bitmap mMask,mBgNor,mGrain;
		int mChangingConfigurations;
		int mGravity = Gravity.FILL;
		Paint mPaint = new Paint();
		int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
		BitmapShader bShader;
		NewBubbleDrawableState(Bitmap mask,Bitmap bgNor,Bitmap grain) {
			mMask = mask;
			mBgNor = bgNor;
			mGrain = grain;
			mPaint.setFilterBitmap(false);
			mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
			bShader = new BitmapShader(grain,TileMode.REPEAT,TileMode.REPEAT);
			mPaint.setShader(bShader);
		}

		NewBubbleDrawableState(NewBubbleDrawableState bitmapState) {
			this(bitmapState.mMask,bitmapState.mBgNor,bitmapState.mGrain);
			mChangingConfigurations = bitmapState.mChangingConfigurations;
			mGravity = bitmapState.mGravity;
			mTargetDensity = bitmapState.mTargetDensity;
			mPaint = new Paint(bitmapState.mPaint);
		}

		@Override
		public Drawable newDrawable() {
			return new NewBubbleDrawable(this, null);
		}

		@Override
		public Drawable newDrawable(Resources res) {
			return new NewBubbleDrawable(this, res);
		}

		@Override
		public int getChangingConfigurations() {
			return mChangingConfigurations;
		}
	}

	private NewBubbleDrawable(NewBubbleDrawableState state, Resources res) {
		mBubbleDrawableState = state;
		if (res != null) {
			mTargetDensity = res.getDisplayMetrics().densityDpi;
		} else {
			mTargetDensity = state.mTargetDensity;
		}
	}
	
	public static void createRepeater(int width,int height,Bitmap src,Canvas canvas,Paint paint) {
		int count = (width + src.getWidth() - 1) / src.getWidth();
		int heightcount = (height + src.getHeight() - 1) / src.getHeight();
		for (int idx = 0; idx < count; ++idx) {
			for(int idx2 = 0; idx2 < heightcount; ++idx2){
				canvas.drawBitmap(src, idx * src.getWidth(), idx2 * src.getHeight(), paint);
			}
		}
	}

}
